home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_061 / microemacs / exec.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  16KB  |  894 lines

  1. /*    This file is for functions dealing with execution of
  2.     commands, command lines, buffers, files and startup files
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "edef.h"
  9.  
  10. #if    MEGAMAX & ST520
  11. overlay    "exec"
  12. #endif
  13.  
  14. #if    DEBUGM
  15. char outline[NSTRING];        /* global string to hold debug line text */
  16. #endif
  17.  
  18. /* namedcmd:    execute a named command even if it is not bound */
  19.  
  20. namedcmd(f, n)
  21.  
  22. int f, n;    /* command arguments [passed through to command executed] */
  23.  
  24. {
  25.     register (*kfunc)();    /* ptr to the requexted function to bind to */
  26.     int (*getname())();
  27.  
  28.     /* prompt the user to type a named command */
  29.     mlwrite(": ");
  30.  
  31.     /* and now get the function name to execute */
  32.     kfunc = getname();
  33.     if (kfunc == NULL) {
  34.         mlwrite("[No such function]");
  35.         return(FALSE);
  36.     }
  37.  
  38.     /* and then execute the command */
  39.     return((*kfunc)(f, n));
  40. }
  41.  
  42. /*    execcmd:    Execute a command line command to be typed in
  43.             by the user                    */
  44.  
  45. execcmd(f, n)
  46.  
  47. int f, n;    /* default Flag and Numeric argument */
  48.  
  49. {
  50.     register int status;        /* status return */
  51.     char cmdstr[NSTRING];        /* string holding command to execute */
  52.  
  53.     /* get the line wanted */
  54.     if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
  55.         return(status);
  56.  
  57.     execlevel = 0;
  58.     return(docmd(cmdstr));
  59. }
  60.  
  61. /*    docmd:    take a passed string as a command line and translate
  62.         it to be executed as a command. This function will be
  63.         used by execute-command-line and by all source and
  64.         startup files. Lastflag/thisflag is also updated.
  65.  
  66.     format of the command line is:
  67.  
  68.         {# arg} <command-name> {<argument string(s)>}
  69.  
  70.     Directives start with a "!" and include:
  71.  
  72.     !endm        End a macro
  73.     !if (cond)    conditional execution
  74.     !else
  75.     !endif
  76.     !return        Return (terminating current macro)
  77.     !goto <label>    Jump to a label in the current macro
  78.  
  79.     Line Labels begin with a "*" in column 1, like:
  80.  
  81.     *LBL01
  82. */
  83.  
  84. docmd(cline)
  85.  
  86. char *cline;    /* command line to execute */
  87.  
  88. {
  89.     register int f;        /* default argument flag */
  90.     register int n;        /* numeric repeat value */
  91.     register int i;
  92.     int (*fnc)();        /* function to execute */
  93.     int status;        /* return status of function */
  94.     int oldcle;        /* old contents of clexec flag */
  95.     int llen;        /* length of cline */
  96.     int force;        /* force TRUE result? */
  97.     char *tmp;        /* tmp pointer into cline */
  98.     struct LINE *lp;    /* a line pointer */
  99.     char *oldestr;        /* original exec string */
  100.     char token[NSTRING];    /* next token off of command line */
  101.     int (*fncmatch())();
  102. #if    DEBUGM
  103.     /* if $debug == TRUE, every line to execute
  104.        gets echoed and a key needs to be pressed to continue
  105.        ^G will abort the command */
  106.     register char *sp;    /* pointer into buf to expand %s */
  107.  
  108.     if (macbug) {
  109.         strcpy(outline, "<<<");
  110. #if    1    /* debug if levels */
  111.         strcat(outline, itoa(execlevel));
  112.         strcat(outline, ":");
  113. #endif
  114.         strcat(outline, cline);
  115.         strcat(outline, ">>>");
  116.  
  117.         /* change all '%' to ':' so mlwrite won't expect arguments */
  118.         sp = outline;
  119.         while (*sp) {
  120.             if (*sp++ == '%')
  121.                 *(sp-1) = ':';
  122.         }
  123.  
  124.         /* write out the debug line */
  125.         mlwrite(outline);
  126.         update(TRUE);
  127.  
  128.         /* and get the keystroke */
  129.         if (tgetc() == 7) {
  130.             mlwrite("[Macro aborted]");
  131.             return(FALSE);
  132.         }
  133.     }
  134. #endif
  135.         
  136.     /* dump comments and labels here */
  137.     if (*cline == ';' || *cline == '*')
  138.         return(TRUE);
  139.  
  140.     /* eat leading spaces */
  141.     while (*cline == ' ' || *cline == '\t')
  142.         ++cline;
  143.  
  144.     /* check to see if this line turns macro storage off */
  145.     if (cline[0] == '!' && strncmp(&cline[1], "endm", 4) == 0) {
  146.         mstore = FALSE;
  147.         bstore = NULL;
  148.         return(TRUE);
  149.     }
  150.  
  151.     /* if macro store is on, just salt this away */
  152.     if (mstore) {
  153.         /* allocate the space for the line */
  154.         llen = strlen(cline);
  155.         if ((lp=lalloc(llen)) == NULL) {
  156.             mlwrite("Out of memory while storing macro");
  157.             return (FALSE);
  158.         }
  159.  
  160.         /* copy the text into the new line */
  161.         for (i=0; i<llen; ++i)
  162.             lputc(lp, i, cline[i]);
  163.  
  164.         /* attach the line to the end of the buffer */
  165.                bstore->b_linep->l_bp->l_fp = lp;
  166.         lp->l_bp = bstore->b_linep->l_bp;
  167.         bstore->b_linep->l_bp = lp;
  168.         lp->l_fp = bstore->b_linep;
  169.         return (TRUE);
  170.     }
  171.     
  172.     force = FALSE;
  173.     oldestr = execstr;    /* save last ptr to string to execute */
  174.     execstr = cline;    /* and set this one as current */
  175.  
  176.     /* process directives */
  177.     if (*cline == '!') {
  178.         /* save directive location and skip it */
  179.         tmp = cline;
  180.         while (*execstr && *execstr != ' ' && *execstr != '\t')
  181.             ++execstr;
  182.  
  183.         if (tmp[1] == 'f' && tmp[2] == 'o') {
  184.             force = TRUE;
  185.             goto do001;
  186.  
  187.         } else if (tmp[1] == 'i' && tmp[2] == 'f') {
  188.  
  189.             /* IF directive */
  190.             /* grab the value of the logical exp */
  191.             if (execlevel == 0) {
  192.                 if ((status = macarg(token)) != TRUE) {
  193.                     execstr = oldestr;
  194.                     return(status);
  195.                 }
  196.                 status = stol(token);
  197.             } else
  198.                 status = TRUE;
  199.  
  200.             if (status) {
  201.  
  202.                 /* IF (TRUE) */
  203.                 if (execlevel != 0)
  204.                     ++execlevel;
  205.             } else {
  206.  
  207.                 /* IF (FALSE) */
  208.                 ++execlevel;
  209.             }
  210.  
  211.         } else if (tmp[1] == 'e' && tmp[2] == 'l') {
  212.  
  213.             /* ELSE directive */
  214.             if (execlevel == 1)
  215.                 --execlevel;
  216.             else if (execlevel == 0 )
  217.                 ++execlevel;
  218.  
  219.         } else if (tmp[1] == 'e' && tmp[2] == 'n') {
  220.  
  221.             /* ENDIF directive */
  222.             if (execlevel)
  223.                 --execlevel;
  224.  
  225.         } else if (tmp[1] == 'r' && tmp[2] == 'e') {
  226.  
  227.             /* RETURN directive */
  228.             execstr = oldestr;
  229.             return(RET);
  230.  
  231.         } else if (tmp[1] == 'g' && tmp[2] == 'o') {
  232.  
  233.             /* GOTO directive */
  234.             /* .....only if we are currently executing */
  235.             if (execlevel) {
  236.                 execstr = oldestr;
  237.                 return(TRUE);
  238.             }
  239.  
  240.             while (*execstr == ' ' || *execstr == '\t')
  241.                 ++execstr;
  242.             strncpy(golabel, execstr, NPAT - 1);
  243.             return(GOLINE);
  244.  
  245.         } else {
  246.             mlwrite("%%Unknown Directive");
  247.             return(FALSE);
  248.         }
  249.  
  250.         /* restore execstr and exit */
  251.         execstr = oldestr;
  252.         return(TRUE);
  253.     }
  254.  
  255. do001:    /* if we are scanning and not executing..go back here */
  256.     if (execlevel) {
  257.         execstr = oldestr;
  258.         return(TRUE);
  259.     }
  260.  
  261.     /* first set up the default command values */
  262.     f = FALSE;
  263.     n = 1;
  264.     lastflag = thisflag;
  265.     thisflag = 0;
  266.  
  267.     if ((status = macarg(token)) != TRUE) {    /* and grab the first token */
  268.         execstr = oldestr;
  269.         return(status);
  270.     }
  271.  
  272.     /* process leadin argument */
  273.     if (gettyp(token) != TKCMD) {
  274.         f = TRUE;
  275.         n = atoi(getval(token));
  276.  
  277.         /* and now get the command to execute */
  278.         if ((status = macarg(token)) != TRUE) {
  279.             execstr = oldestr;
  280.             return(status);    
  281.         }    
  282.     }
  283.  
  284.     /* and match the token to see if it exists */
  285.     if ((fnc = fncmatch(token)) == NULL) {
  286.         mlwrite("[No such Function]");
  287.         execstr = oldestr;
  288.         return(FALSE);
  289.     }
  290.     
  291.     /* save the arguments and go execute the command */
  292.     oldcle = clexec;        /* save old clexec flag */
  293.     clexec = TRUE;            /* in cline execution */
  294.     status = (*fnc)(f, n);        /* call the function */
  295.     cmdstatus = status;        /* save the status */
  296.     if (force)            /* force the status */
  297.         status = TRUE;
  298.     clexec = oldcle;        /* restore clexec flag */
  299.     execstr = oldestr;
  300.     return(status);
  301. }
  302.  
  303. /* token:    chop a token off a string
  304.         return a pointer past the token
  305. */
  306.  
  307. char *token(src, tok)
  308.  
  309. char *src, *tok;    /* source string, destination token string */
  310.  
  311. {
  312.     register int quotef;    /* is the current string quoted? */
  313.  
  314.     /* first scan past any whitespace in the source string */
  315.     while (*src == ' ' || *src == '\t')
  316.         ++src;
  317.  
  318.     /* scan through the source string */
  319.     quotef = FALSE;
  320.     while (*src) {
  321.         /* process special characters */
  322.         if (*src == '~') {
  323.             ++src;
  324.             if (*src == 0)
  325.                 break;
  326.             switch (*src++) {
  327.                 case 'r':    *tok++ = 13; break;
  328.                 case 'n':    *tok++ = 10; break;
  329.                 case 't':    *tok++ = 9;  break;
  330.                 case 'b':    *tok++ = 8;  break;
  331.                 case 'f':    *tok++ = 12; break;
  332.                 default:    *tok++ = *(src-1);
  333.             }
  334.         } else {
  335.             /* check for the end of the token */
  336.             if (quotef) {
  337.                 if (*src == '"')
  338.                     break;
  339.             } else {
  340.                 if (*src == ' ' || *src == '\t')
  341.                     break;
  342.             }
  343.  
  344.             /* set quote mode if qoute found */
  345.             if (*src == '"')
  346.                 quotef = TRUE;
  347.  
  348.             /* record the character */
  349.             *tok++ = *src++;
  350.         }
  351.     }
  352.  
  353.     /* terminate the token and exit */
  354.     if (*src)
  355.         ++src;
  356.     *tok = 0;
  357.     return(src);
  358. }
  359.  
  360. macarg(tok)    /* get a macro line argument */
  361.  
  362. char *tok;    /* buffer to place argument */
  363.  
  364. {
  365.     int savcle;    /* buffer to store original clexec */
  366.     int status;
  367.  
  368.     savcle = clexec;    /* save execution mode */
  369.     clexec = TRUE;        /* get the argument */
  370.     status = nextarg("", tok, NSTRING, ctoec('\n'));
  371.     clexec = savcle;    /* restore execution mode */
  372.     return(status);
  373. }
  374.  
  375. /*    nextarg:    get the next argument    */
  376.  
  377. nextarg(prompt, buffer, size, terminator)
  378.  
  379. char *prompt;        /* prompt to use if we must be interactive */
  380. char *buffer;        /* buffer to put token into */
  381. char *size;        /* size of the buffer */
  382. int terminator;        /* terminating char to be used on interactive fetch */
  383.  
  384. {
  385.     /* if we are interactive, go get it! */
  386.     if (clexec == FALSE)
  387.         return(getstring(prompt, buffer, size, terminator));
  388.  
  389.     /* grab token and advance past */
  390.     execstr = token(execstr, buffer);
  391.  
  392.     /* evaluate it */
  393.     strcpy(buffer, getval(buffer));
  394.     return(TRUE);
  395. }
  396.  
  397. /*    storemac:    Set up a macro buffer and flag to store all
  398.             executed command lines there            */
  399.  
  400. storemac(f, n)
  401.  
  402. int f;        /* default flag */
  403. int n;        /* macro number to use */
  404.  
  405. {
  406.     register struct BUFFER *bp;    /* pointer to macro buffer */
  407.     char bname[NBUFN];        /* name of buffer to use */
  408.  
  409.     /* must have a numeric argument to this function */
  410.     if (f == FALSE) {
  411.         mlwrite("No macro specified");
  412.         return(FALSE);
  413.     }
  414.  
  415.     /* range check the macro number */
  416.     if (n < 1 || n > 40) {
  417.         mlwrite("Macro number out of range");
  418.         return(FALSE);
  419.     }
  420.  
  421.     /* construct the macro buffer name */
  422.     strcpy(bname, "[Macro xx]");
  423.     bname[7] = '0' + (n / 10);
  424.     bname[8] = '0' + (n % 10);
  425.  
  426.     /* set up the new macro buffer */
  427.     if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
  428.         mlwrite("Can not create macro");
  429.         return(FALSE);
  430.     }
  431.  
  432.     /* and make sure it is empty */
  433.     bclear(bp);
  434.  
  435.     /* and set the macro store pointers to it */
  436.     mstore = TRUE;
  437.     bstore = bp;
  438.     return(TRUE);
  439. }
  440.  
  441. /*    execbuf:    Execute the contents of a buffer of commands    */
  442.  
  443. execbuf(f, n)
  444.  
  445. int f, n;    /* default flag and numeric arg */
  446.  
  447. {
  448.         register BUFFER *bp;        /* ptr to buffer to execute */
  449.         register int status;        /* status return */
  450.         char bufn[NBUFN];        /* name of buffer to execute */
  451.  
  452.     /* find out what buffer the user wants to execute */
  453.         if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
  454.                 return(status);
  455.  
  456.     /* find the pointer to that buffer */
  457.         if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
  458.         mlwrite("No such buffer");
  459.                 return(FALSE);
  460.         }
  461.  
  462.     /* and now execute it as asked */
  463.     while (n-- > 0)
  464.         if ((status = dobuf(bp)) != TRUE)
  465.             return(status);
  466.     return(TRUE);
  467. }
  468.  
  469. /*    dobuf:    execute the contents of the buffer pointed to
  470.         by the passed BP                */
  471.  
  472. dobuf(bp)
  473.  
  474. BUFFER *bp;    /* buffer to execute */
  475.  
  476. {
  477.         register int status;        /* status return */
  478.     register LINE *lp;        /* pointer to line to execute */
  479.     register LINE *hlp;        /* pointer to line header */
  480.     register LINE *glp;        /* line to goto */
  481.     register int linlen;        /* length of line to execute */
  482.     register WINDOW *wp;        /* ptr to windows to scan */
  483.     char *eline;            /* text of line to execute */
  484.  
  485.     /* clear IF level flags */
  486.     execlevel = 0;
  487.  
  488.     /* starting at the beginning of the buffer */
  489.     hlp = bp->b_linep;
  490.     lp = hlp->l_fp;
  491.     while (lp != hlp) {
  492.         /* allocate eline and copy macro line to it */
  493.         linlen = lp->l_used;
  494.         if ((eline = malloc(linlen+1)) == NULL) {
  495.             mlwrite("%%Out of Memory during macro execution");
  496.             return(FALSE);
  497.         }
  498.         strncpy(eline, lp->l_text, linlen);
  499.         eline[linlen] = 0;    /* make sure it ends */
  500.  
  501.         /* trim leading whitespace */
  502.         while (eline[0] == ' ' || eline[0] == '\t')
  503.             strcpy(eline, &eline[1]);
  504.  
  505.         /* if it is not a comment, execute it */
  506.         if (eline[0] != 0 && eline[0] != ';') {
  507.             status = docmd(eline);
  508.  
  509.             /* if it is a !GOTO directive, deal with it */
  510.             if (status == GOLINE) {
  511.                 linlen = strlen(golabel);
  512.                 glp = hlp->l_fp;
  513.                 while (glp != hlp) {
  514.                     if (*glp->l_text == '*' &&
  515.                         (strncmp(&glp->l_text[1], golabel,
  516.                                 linlen) == 0)) {
  517.                         lp = glp;
  518.                         status = TRUE;
  519.                     }
  520.                 glp = glp->l_fp;
  521.                 }
  522.             }
  523.  
  524.             if (status == GOLINE) {
  525.                 mlwrite("%%No such label");
  526.                 return(FALSE);
  527.             }
  528.  
  529.             /* if it is a !RETURN directive...do so */
  530.             if (status == RET) {
  531.                 free(eline);
  532.                 break;
  533.             }
  534.  
  535.             /* check for a command error */
  536.             if (status != TRUE) {
  537.                 /* look if buffer is showing */
  538.                 wp = wheadp;
  539.                 while (wp != NULL) {
  540.                     if (wp->w_bufp == bp) {
  541.                         /* and point it */
  542.                         wp->w_dotp = lp;
  543.                         wp->w_doto = 0;
  544.                         wp->w_flag |= WFHARD;
  545.                     }
  546.                     wp = wp->w_wndp;
  547.                 }
  548.                 /* in any case set the buffer . */
  549.                 bp->b_dotp = lp;
  550.                 bp->b_doto = 0;
  551.                 free(eline);
  552.                 execlevel = 0;
  553.                 return(status);
  554.             }
  555.         }
  556.  
  557.         /* on to the next line */
  558.         free(eline);
  559.         lp = lp->l_fp;
  560.     }
  561.  
  562.     /* exit the current function */
  563.     execlevel = 0;
  564.         return(TRUE);
  565. }
  566.  
  567. execfile(f, n)    /* execute a series of commands in a file
  568. */
  569.  
  570. int f, n;    /* default flag and numeric arg to pass on to file */
  571.  
  572. {
  573.     register int status;    /* return status of name query */
  574.     char *fname[NSTRING];    /* name of file to execute */
  575.  
  576.     if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
  577.         return(status);
  578.  
  579.     /* otherwise, execute it */
  580.     while (n-- > 0)
  581.         if ((status=dofile(fname)) != TRUE)
  582.             return(status);
  583.  
  584.     return(TRUE);
  585. }
  586.  
  587. /*    dofile:    yank a file into a buffer and execute it
  588.         if there are no errors, delete the buffer on exit */
  589.  
  590. dofile(fname)
  591.  
  592. char *fname;    /* file name to execute */
  593.  
  594. {
  595.     register BUFFER *bp;    /* buffer to place file to exeute */
  596.     register BUFFER *cb;    /* temp to hold current buf while we read */
  597.     register int status;    /* results of various calls */
  598.     char bname[NBUFN];    /* name of buffer */
  599.  
  600.     makename(bname, fname);        /* derive the name of the buffer */
  601.     if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
  602.         return(FALSE);
  603.  
  604.     bp->b_mode = MDVIEW;    /* mark the buffer as read only */
  605.     cb = curbp;        /* save the old buffer */
  606.     curbp = bp;        /* make this one current */
  607.     /* and try to read in the file to execute */
  608.     if ((status = readin(fname, FALSE)) != TRUE) {
  609.         curbp = cb;    /* restore the current buffer */
  610.         return(status);
  611.     }
  612.  
  613.     /* go execute it! */
  614.     curbp = cb;        /* restore the current buffer */
  615.     if ((status = dobuf(bp)) != TRUE)
  616.         return(status);
  617.  
  618.     /* if not displayed, remove the now unneeded buffer and exit */
  619.     if (bp->b_nwnd == 0)
  620.         zotbuf(bp);
  621.     return(TRUE);
  622. }
  623.  
  624. /*    cbuf:    Execute the contents of a numbered buffer    */
  625.  
  626. cbuf(f, n, bufnum)
  627.  
  628. int f, n;    /* default flag and numeric arg */
  629. int bufnum;    /* number of buffer to execute */
  630.  
  631. {
  632.         register BUFFER *bp;        /* ptr to buffer to execute */
  633.         register int status;        /* status return */
  634.     static char bufname[] = "[Macro xx]";
  635.  
  636.     /* make the buffer name */
  637.     bufname[7] = '0' + (bufnum / 10);
  638.     bufname[8] = '0' + (bufnum % 10);
  639.  
  640.     /* find the pointer to that buffer */
  641.         if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
  642.             mlwrite("Macro not defined");
  643.                 return(FALSE);
  644.         }
  645.  
  646.     /* and now execute it as asked */
  647.     while (n-- > 0)
  648.         if ((status = dobuf(bp)) != TRUE)
  649.             return(status);
  650.     return(TRUE);
  651. }
  652.  
  653. cbuf1(f, n)
  654.  
  655. {
  656.     cbuf(f, n, 1);
  657. }
  658.  
  659. cbuf2(f, n)
  660.  
  661. {
  662.     cbuf(f, n, 2);
  663. }
  664.  
  665. cbuf3(f, n)
  666.  
  667. {
  668.     cbuf(f, n, 3);
  669. }
  670.  
  671. cbuf4(f, n)
  672.  
  673. {
  674.     cbuf(f, n, 4);
  675. }
  676.  
  677. cbuf5(f, n)
  678.  
  679. {
  680.     cbuf(f, n, 5);
  681. }
  682.  
  683. cbuf6(f, n)
  684.  
  685. {
  686.     cbuf(f, n, 6);
  687. }
  688.  
  689. cbuf7(f, n)
  690.  
  691. {
  692.     cbuf(f, n, 7);
  693. }
  694.  
  695. cbuf8(f, n)
  696.  
  697. {
  698.     cbuf(f, n, 8);
  699. }
  700.  
  701. cbuf9(f, n)
  702.  
  703. {
  704.     cbuf(f, n, 9);
  705. }
  706.  
  707. cbuf10(f, n)
  708.  
  709. {
  710.     cbuf(f, n, 10);
  711. }
  712.  
  713. cbuf11(f, n)
  714.  
  715. {
  716.     cbuf(f, n, 11);
  717. }
  718.  
  719. cbuf12(f, n)
  720.  
  721. {
  722.     cbuf(f, n, 12);
  723. }
  724.  
  725. cbuf13(f, n)
  726.  
  727. {
  728.     cbuf(f, n, 13);
  729. }
  730.  
  731. cbuf14(f, n)
  732.  
  733. {
  734.     cbuf(f, n, 14);
  735. }
  736.  
  737. cbuf15(f, n)
  738.  
  739. {
  740.     cbuf(f, n, 15);
  741. }
  742.  
  743. cbuf16(f, n)
  744.  
  745. {
  746.     cbuf(f, n, 16);
  747. }
  748.  
  749. cbuf17(f, n)
  750.  
  751. {
  752.     cbuf(f, n, 17);
  753. }
  754.  
  755. cbuf18(f, n)
  756.  
  757. {
  758.     cbuf(f, n, 18);
  759. }
  760.  
  761. cbuf19(f, n)
  762.  
  763. {
  764.     cbuf(f, n, 19);
  765. }
  766.  
  767. cbuf20(f, n)
  768.  
  769. {
  770.     cbuf(f, n, 20);
  771. }
  772.  
  773. cbuf21(f, n)
  774.  
  775. {
  776.     cbuf(f, n, 21);
  777. }
  778.  
  779. cbuf22(f, n)
  780.  
  781. {
  782.     cbuf(f, n, 22);
  783. }
  784.  
  785. cbuf23(f, n)
  786.  
  787. {
  788.     cbuf(f, n, 23);
  789. }
  790.  
  791. cbuf24(f, n)
  792.  
  793. {
  794.     cbuf(f, n, 24);
  795. }
  796.  
  797. cbuf25(f, n)
  798.  
  799. {
  800.     cbuf(f, n, 25);
  801. }
  802.  
  803. cbuf26(f, n)
  804.  
  805. {
  806.     cbuf(f, n, 26);
  807. }
  808.  
  809. cbuf27(f, n)
  810.  
  811. {
  812.     cbuf(f, n, 27);
  813. }
  814.  
  815. cbuf28(f, n)
  816.  
  817. {
  818.     cbuf(f, n, 28);
  819. }
  820.  
  821. cbuf29(f, n)
  822.  
  823. {
  824.     cbuf(f, n, 29);
  825. }
  826.  
  827. cbuf30(f, n)
  828.  
  829. {
  830.     cbuf(f, n, 30);
  831. }
  832.  
  833. cbuf31(f, n)
  834.  
  835. {
  836.     cbuf(f, n, 31);
  837. }
  838.  
  839. cbuf32(f, n)
  840.  
  841. {
  842.     cbuf(f, n, 32);
  843. }
  844.  
  845. cbuf33(f, n)
  846.  
  847. {
  848.     cbuf(f, n, 33);
  849. }
  850.  
  851. cbuf34(f, n)
  852.  
  853. {
  854.     cbuf(f, n, 34);
  855. }
  856.  
  857. cbuf35(f, n)
  858.  
  859. {
  860.     cbuf(f, n, 35);
  861. }
  862.  
  863. cbuf36(f, n)
  864.  
  865. {
  866.     cbuf(f, n, 36);
  867. }
  868.  
  869. cbuf37(f, n)
  870.  
  871. {
  872.     cbuf(f, n, 37);
  873. }
  874.  
  875. cbuf38(f, n)
  876.  
  877. {
  878.     cbuf(f, n, 38);
  879. }
  880.  
  881. cbuf39(f, n)
  882.  
  883. {
  884.     cbuf(f, n, 39);
  885. }
  886.  
  887. cbuf40(f, n)
  888.  
  889. {
  890.     cbuf(f, n, 40);
  891. }
  892.  
  893.  
  894.